﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;

namespace Acoris.Parser
{
    /// <summary>
    /// 表示字符流
    /// </summary>
    public sealed class CharacterStream
    {
        readonly string _text;
        int _offset;
        int _length;

        public CharacterStream(string text)
        {
            Debug.Assert(text != null);
            _text = text ?? throw new NullReferenceException();
            _length = _text.Length;
        }

        #region Method

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public char Next()
        {
            return GetValue(_offset++);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public char Current()
        {
            return GetValue(_offset);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="position"></param>
        public void Move(int position)
        {
            _offset += position;
        }

        private char GetValue(int position)
        {
            if (position < 0 || position >= _text.Length) {
                throw new IndexOutOfRangeException();
            }
            return _text[position];
        }

        public bool IsAnyWord()
        {
            var ch = Current();
            switch (ch) {
                case '\\':
                case '-':
                case '&':
                case '!':
                case '<':
                case '>':
                case '/':
                case ';':
                case '\x20':
                case '\r':
                case '\n':
                    return false;
                default:
                    return true;
            }
        }

        #endregion

        #region Property

        /// <summary>
        /// 获取当前字符流的位置
        /// </summary>
        public int Position {
            get {
                return _offset;
            }
        }

        /// <summary>
        /// 获取当前字符流所代表的字符串
        /// </summary>
        public string Text {
            get {
                return _text;
            }
        }

        /// <summary>
        /// 指示当前字符流是否到达字符流末端
        /// </summary>
        public bool EndOfFile {
            get {
                return _offset >= _text.Length;
            }
        }
        #endregion

        #region Override

        /// <summary>
        /// 返回当前字符流带的哈希值
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode() ^ this._text.GetHashCode();
        }

        /// <summary>
        /// 判断制定对象是否与当前字符串流相等
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj is CharacterStream cs) {
                return cs._text == this._text;
            }
            return false;
        }

        /// <summary>
        /// 返回当前字符流位置的字符
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return $"Length:{_length},Position:{_offset},Char:{_text[_offset]}";
        }

        #endregion
    }
}
